skills(pm-dispatch): clause-② cards build at the default tier and are gated by the contract review at CONTRACT_REVIEW_TIER (#16905) - #16915
Conversation
… gated by the contract review at CONTRACT_REVIEW_TIER 强制条款② mandated CONTRACT_REVIEW_TIER for the BUILD of any card that widens the accept set or the public surface, while the architecture already declares the review at that tier to be the compensation for low-tier dispatch (references/ contract-review.md 降档保险丝; the 2026-08-20 「fable 当审计师用,不当施工队用」 ruling recorded in scripts/pm/dispatch-gates.mjs). Narrow the text: clause-② cards build at the default judgment tier and are reviewed at CONTRACT_REVIEW_TIER; the carrier discipline, 条款①, the tier fuse and the enqueue gate's outcome are unchanged. The now-dead tier predicate on the enqueue gate and the now-vacuous quota-exemption sentence are deleted; the counter (contract-review FAIL rate on default-tier clause-② builds, revert if materially above at-tier builds) lands in the round-report section. Line count 811 → 811 under the shrink-only ratchet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TezFG8ZMrNH6n5VTNpPpdH
维护者速读(补丁轮后,head
|
Contract review (
|
| line | old | new | faithful narrowing? | content lost? |
|---|---|---|---|---|
| :514 | 凡放宽接受集或扩大公开面的卡一律契约复审档;拉回已声明契约按常规档 | 凡放宽接受集或扩大公开面的卡默认判断档施工、契约复审档复核 | yes — build tier lowered, review tier kept; the mechanism is the pre-existing :512 「降档施工的补偿控制 = 复核席跑契约复审档」 | no. Carrier discipline still stated at :646 「needs:contract-review … 由 PR 创建者随可复审契约增量同笔挂」 and :647 「Clause-②: yes 认领同笔在卡上挂标」 (+ os-dev.md:286). No conflict with the exemption floor :526 「仅当契约复审档实测不可用才落默认判断档,⛔ 不再往下」 (build tier now equals the floor) nor with contract-review.md:60 (review never downgrades; unchanged). |
| :517 | 条款②只指已发布契约面。 | 条款②只指已发布契约面,拉回已声明契约不触它;卡面复述仍是条款②。 | yes | no. 「不触它」 matches lanes/spec.md:19 「收窄仍是语义面,不触条款②」 and the following negative-boundary lines :518-520 (删误拒 = no with Contract-text: citation) read the same before and after. 「卡面复述仍是条款②」 is the first half of old :522, relocated. |
| :522 | 卡面对条款②的复述仍是条款②;额度耗尽豁免及其 needs:contract-review 补偿一并及于它。 |
(deleted) | n/a | no. First half → :517. Second half's guarantees: exemption floor = default tier (:526), which is now the clause-② build tier anyway; the needs:contract-review compensation hangs on every Clause-②: yes regardless of tier (:646-647); the review itself never takes the exemption (contract-review.md:60). Every guarantee has a home. |
| :525→:524 | …skills 席与条款②工作。 | …skills 席与条款②复核。 | yes — ceiling reserved for the review, consistent with :514 | no |
| :640→:639 | 双肢命中任一且派发档位低于契约复审档 ⇒ ⛔ 禁止入队 | 双肢命中任一 ⇒ 无席内契约复审档 PASS 在案 ⛔ 禁止入队 | mixed — see finding 2. The tier predicate is dead under :514 (every clause-② build is below the ceiling, so the old line would read "never enqueue"). The new predicate 「PASS 在案」 is defined at contract-review.md:41 落地前检① 「席内契约档 PASS 在案,即卡上的达档裁决评论」. |
the tier bar is dropped deliberately (it is what the PR changes); no other content lost |
| (new) :675 | — | 复审清单计条款②默认档施工的复审 FAIL 率,基线待测;实质高于达档施工 ⇒ 条款②回退。 | tripwire, as the claim required | n/a — see finding 3 |
Gate readings (extracted tree of bd26a0839, dependency-free scripts run by this seat)
node scripts/pm/check-skill-line-ratchet.mjs→ exit 0,SKILL.md is 811 lines (ceiling 811; headroom 0). Re-measured: 811 lines; changed lines 514/517/524/639/675 are 108 / 97 / 79 / 118 / 120 bytes (:675 is exactly at the 120-byte budget).node scripts/check-skill-frame-sync.mjs→ exit 0,2 copies … structurally isomorphic.node scripts/pm/check-skill-id-lint.mjs→ exit 0,26 file(s) clean.node scripts/check-skill-frame-freshness.mjs→ exit 0 but proves nothing in an extracted tree (freshness could NOT be established: there is no origin/main). Substituted: frame block :734-752 md522f2339f0acb64cdb50c7adc9db681c3on merge-base, on head, and on currentorigin/main70f7d6d73— identical all three.- Diff vs merge-base: exactly one file;
origin/mainsince the merge-base does not touch.claude/skills/**,.claude/agents/os-dev.mdorAGENTS.md. - Commit
bd26a0839trailers:Co-Authored-By+Claude-Sessiononly — no closing keyword /Part-of/Refsbound to a card (RULE 2 ofscripts/check-partof-closing-keyword.mjs); CI checkPart-of PR must not also close its cardgreen. - Four governed pieces:
draft: true✓ · labelsneeds-user-decision+skip-changeset(+documentation,size/s) ✓ · 速读 comment 5588349195 ✓ · reviewershotlong,os-zhuang✓.mergeable_state: blocked(draft + required review — expected). - CI (
get_check_runs, 32 runs): polled once at 16:28Z — 30 of 32 completed (16success, 14skipped, 0 failures); 2 stillin_progressat 16:28Z:Lint & Repo Gates(job 102142928896) andType Check · workspace(job 102142928428), both started 16:19Z. Not a green reading; the director seat re-reads CI before recording. This diff is markdown-only, outside eslint'sfilespopulation, so neither job's verdict can vary with it.
Findings
-
[major] The protocol still contradicts itself on the clause-② build tier inside
references/**, and none of it is in pm(dispatch-gates): clause-② prose in dispatch-gates.mjs (docblocks + every--tierprintout) and core-rules.md:124 still describes a BUILD-tier mandate once the 强制条款② narrowing lands #16914. After this PR,SKILL.md:514says default-tier build, while on the same head:references/contract-review.md:10「Clause-②: yes | no按设计临时:只定派发档位的保守方向」 — the declaration's stated purpose is to set the dispatch tier, which it no longer does;references/contract-review.md:13「新导出符号或已发布载荷上的新键恒yes,直接锁契约复审档」 — a claim-time lock of the ceiling for the build;references/contract-review.md:15「claim 拿不准 ⇒ 按yes派契约复审档」 — an explicit instruction to dispatch atCONTRACT_REVIEW_TIER;references/core-rules.md:113「派发调用 … 协议语义面与契约变更卡恒走契约复审档」 — an explicit dispatch mandate for contract-change cards;references/lanes/cli.md:18「条款②从卡内容判且优先于它」 — clause ② overriding the path-derived tier floor only makes sense if clause ② sets a build tier.
pm(dispatch-gates): clause-② prose in dispatch-gates.mjs (docblocks + every
--tierprintout) and core-rules.md:124 still describes a BUILD-tier mandate once the 强制条款② narrowing lands #16914 exists and covers exactly what its body lists:scripts/pm/dispatch-gates.mjsprose (three sites) andcore-rules.md:124. It does not cover the five lines above, and the PR body's "Untouched" paragraph presentsreferences/contract-review.mdas consistent with the change (「the tier fuse … untouched」) without disclosing that :13/:15 of the same file mandate the opposite build tier. The claim fencedcontract-review.mdout of the file surface unless the counter lived there, so the dev could not edit it — but the claim also says 「stop on breach; explain in the report」, and the report explains neither. A PM readingcontract-review.md:15after this lands is told to dispatch at the ceiling; one readingSKILL.md:514is told not to.
Expectation: either (a) the director widens the surface and this PR rewrites those five lines in place — all five can be reworded line-neutrally (e.g. :15 「claim 拿不准 ⇒ 按yes挂标走契约复审档复核」, :13 「…恒yes,直接锁契约复审档复核」, core-rules :113 「协议语义面卡恒走契约复审档,契约变更卡恒过契约复审档复核」), so the ratchet (contract-review.md 60/60, core-rules.md 150/150, cli.md 29/29) is not disturbed; or (b) the maintainer accepts the interim contradiction explicitly, in which case pm(dispatch-gates): clause-② prose in dispatch-gates.mjs (docblocks + every--tierprintout) and core-rules.md:124 still describes a BUILD-tier mandate once the 强制条款② narrowing lands #16914 must be widened to name these five sites and the PR body's "Untouched" paragraph must disclose them. (a) is the smaller total change; the choice is the maintainer's. -
[minor] :639 — direction of the gate change is not "outcome unchanged" as the body says; it is the stricter of skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912's two readings and stricter than skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912's own proposal. Old text, literal (Reading A of skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912): any path-limb hit + below-ceiling dispatch ⇒ hard bar, no exit. Old text as the instrument reads it (Reading B): the diff is adjudicated, any tier can pass. New text: any limb hit ⇒ an in-seat
CONTRACT_REVIEW_TIERPASS on record is the only exit, regardless of tier. Consequences: (i) for an at-tier build the gate line itself now demands a PASS, where before only :643 / 落地前检① did — narrowing; (ii) for a below-tier build the absolute bar becomes a PASS requirement — the only reading compatible with :514, and it removes the lane freeze skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912 reports; (iii) for aClause-②: noPR whose diff merely touchespackages/spec/src/**(path limb), a PASS is now required — skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912 records that fix(spec): isValueDomainMember refuses an off-vocabulary domain instead of failing open #16899 / docs(spec): say on the title grade which INPUT it describes #16901 were enqueued on--pairexit 0 without a PASS, and skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912's suggested wording would only bar ayesverdict below tier.lanes/spec.md:33「条款②路径肢照命中,入队前仍过契约复核」 already states (iii) for the pre-approved ledger class, so the new line is consistent with the lane's own rule and with 「按更严的一条行动」 — defensible; but the 速读 tells the maintainer 「闸门不变」, which is only true against Reading A + :643. So skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912 describes exactly this ambiguity and this line resolves it. Not deciding skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912 here.
Expectation: the 速读 / PR body says in one sentence that every path-limb hit now needs an at-tier PASS to enqueue, includingClause-②: nospec-lane PRs, so the maintainer rules on that knowingly; if that is not intended, :639 needs 「判定yes」 inserted before the PASS clause (fits the 120-byte budget only with compression). -
[minor] :675 — the recording half is executable, the revert half is not. Who/where/when: the round-report writer, in the 复审清单 section that
contract-review.md:40does define (「轮次报告设复审清单专节,形状与代裁清单同为强制审计」), every round — fine. But 「实质高于达档施工 ⇒ 条款②回退」 names no actor, no threshold, and its comparison arm 「达档施工」 is produced by nothing in the rule once every clause-② card builds at the default tier: the at-tier sample stays at the historical 1/1 unless a PM keeps exercising :508 「按卡取用」 discretion. 「基线待测」 admits this but does not say who will measure it. The revert itself is a governed-text change, so the seat's only executable action is to escalate — the line does not say so.
Expectation: non-blocking. Acceptable as-is if the maintainer treats the counter as a report line that feeds a human decision; otherwise the line should name the escalation (决策箱) as the trigger's output. -
[info, non-blocking] PR body carries two attribution footers (a bare footer, then
---+ footer, appended by the platform on create). AGENTS.md:432 「⛔ never re-send a body that already carries an appended footer」 — correctly left alone. -
[info] Process. The freshness gate cannot be run meaningfully outside a git checkout; the md5 substitute above is the reading. The dev's claim recorded
CONTRACT_REVIEW_TIERfor the build, as 条款① requires for this file; this seat did not verify the transcript (contract-review.md:56) — that reading belongs to the dispatching seat.
Maintainer-only merge: yes
Generated by Claude Code
… default-tier build, and give the tripwire an actor and a frozen comparison arm Patch round after the tier contract review. The five references/** lines that still described a clause-② card as BUILT or dispatched at CONTRACT_REVIEW_TIER (contract-review.md :10 :13 :15, core-rules.md :113, lanes/cli.md :18) now say the declaration and the mandate govern the REVIEW tier only; core-rules.md :124 names the at-tier review PASS, not an unspecified tier, as what a contract card lacks when it is barred from the queue. The SKILL.md :675 counter line now names who records the rate (the seat writing the round report), compares it against the historical at-tier-built FAIL rate frozen before this change, and routes a revert to the maintainer as a decision card rather than a seat act. Every touched file keeps its line count (811 / 60 / 150 / 29) and every rewritten line is within the 120-byte budget. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TezFG8ZMrNH6n5VTNpPpdH
Contract review (
|
| # | sev | status | evidence on e1edc4196 |
|---|---|---|---|
| F1 | major | closed on the text; body disclosure half open (→ finding 1) | all five lines rewritten in place, line-neutral (below). Residual grep of .claude/skills/pm-dispatch/** + .claude/agents/os-dev.md for 条款② / Clause-② / 契约复审档 / CONTRACT_REVIEW_TIER / 契约卡 / 契约变更 / 档位不足 / 派契约复审档 / 锁契约复审档 / 一律契约复审档: 0 remaining clause-② BUILD/dispatch-tier mandates. What remains is 条款① (SKILL.md:509, lanes/skills.md:20 「pm-dispatch 根恒契约复审档」), the ceiling definition (SKILL.md:508), review-tier statements (SKILL.md:512-513,524,612,629,642, contract-review.md:10,13,15,52,55,57) and carrier lines. #16914's body was re-scoped (updated 16:32:56Z): scripts/pm/dispatch-gates.mjs prose only, three sites, core-rules.md:124 removed from it. #16836's overlap on contract-review.md is disclosed in the 速读 (item ③) but the PR body still says the file is not touched — that is the open half. |
| F2 | minor | half closed: 速读 yes, PR body no | 速读 item ② states it: every path-limb hit (packages/spec/src/**), Clause-②: yes or no, any build tier ⇒ the sole exit is an in-seat at-tier PASS on record; stricter than #16912's recorded practice; #16912 not decided. Head SKILL.md:639 「双肢命中任一 ⇒ 无席内契约复审档 PASS 在案 ⛔ 禁止入队」 does exactly that (the declaration limb at :641 and the path limb at :640 are OR-ed by 「任一」; the no declaration does not un-hit the path limb). The PR body does not say it — the body still describes bd26a0839 (→ finding 1). |
| F3 | minor | closed | SKILL.md:675 「报告席记条款②默认档 FAIL 率入复审清单;超改制前达档史值 ⇒ 决策卡交维护者定回退。」 — actor 报告席 ✓, comparison arm = the at-tier-built historical value frozen before the change ✓, revert = decision card to the maintainer, not a seat act ✓, 119 B ✓. See info finding 3 on the arm's sample size. |
| F4 | info | unchanged | body still carries two attribution footers; AGENTS.md:432 forbids re-sending a body that already carries the appended one — correctly left alone as a footer matter; the body's content is now the problem (finding 1). |
| F5 | info | unchanged | tier of the build seat not verified by this seat (transcript reading belongs to the dispatching seat). |
F1 per-line reading (origin/main → e1edc4196)
| file:line | old | new | faithful (build at default tier, review at CONTRACT_REVIEW_TIER)? |
|---|---|---|---|
contract-review.md:10 |
Clause-②: yes | no 按设计临时:只定派发档位的保守方向,⛔ 非终审。 |
…按设计临时:只定是否必过契约复审档复核的保守方向,⛔ 非终审。 | yes — the declaration now governs the review obligation, not the dispatch tier (112 B) |
contract-review.md:13 |
…新导出符号或已发布载荷上的新键恒 yes,直接锁契约复审档。 |
…恒 yes,锁契约复审档复核。 |
yes (116 B) |
contract-review.md:15 |
claim 拿不准 ⇒ 按 yes 派契约复审档;… |
claim 拿不准 ⇒ 按 yes 挂标走契约复审档复核;… |
yes — 挂标 matches the carrier rule at SKILL.md:646-647 (116 B) |
core-rules.md:113 |
…档位逐卡显式传参,协议语义面与契约变更卡恒走契约复审档。 | …档位逐卡显式传参;语义面卡恒契约复审档施工,契约变更卡恒其复核。 | yes — 条款① build kept, 条款② becomes review-only (119 B) |
core-rules.md:124 (6th line, not in the F1 list) |
…档位不足的契约卡 ⛔ 禁止入队。 | …无达档复核 PASS 的契约卡 ⛔ 禁止入队。 | yes — restates head SKILL.md:639 (115 B) |
lanes/cli.md:18 |
dispatch-gates.mjs 只报路径推导的地板,条款②从卡内容判且优先于它。 |
…只报路径推导的地板;条款②从卡内容判,只定复核档不定施工档。 | yes — 「优先于它」 (clause ② overriding the path floor for the build) is dropped because clause ② no longer sets a build tier; the 条款① path floor itself is untouched (109 B) |
Measurements (extracted tree of e1edc4196)
- Line counts head /
origin/main:SKILL.md811/811 ·contract-review.md60/60 ·core-rules.md150/150 ·lanes/cli.md29/29. - Diff vs
origin/main: exactly 4 files, 11 insertions / 11 deletions (SKILL.md 5/5, contract-review.md 3/3, core-rules.md 2/2, cli.md 1/1). Patch commite1edc4196alone (vs its parentb5be3f049): the same 4 files, 7/7. The merge commitb5be3f049adds nothing of its own (diff bd26a0839..b5be3f049 -- .claude AGENTS.md CLAUDE.md scripts/pmis empty;diff origin/main..b5be3f049is onlybd26a0839's SKILL.md 5/5). The rawbd26a0839..head --statshows 20 files because it spans the main merge — all 16 extra files areorigin/main's, none is the PR's.scripts/pm/**,.claude/agents/os-dev.md,AGENTS.md,CLAUDE.md,content/docs/releases/**untouched. - Every added line ≤ 120 B: max added line is 119 B (:675); changed lines measured individually: 108 / 97 / 79 / 118 / 119 / 112 / 116 / 116 / 119 / 115 / 109 B.
- Frame block
SKILL.md:734-752md522f2339f0acb64cdb50c7adc9db681c3on head and onorigin/main70f7d6d73— unchanged. node scripts/pm/check-skill-line-ratchet.mjs→ exit 0; the four touched files read811 (ceiling 811),60 (ceiling 60),150 (ceiling 150),29 (ceiling 29), headroom 0 each;total ceilings down 9 lines.node scripts/check-skill-frame-sync.mjs→ exit 0,2 copies … structurally isomorphic across 2 files.node scripts/pm/check-skill-id-lint.mjs→ exit 0,26 file(s) clean.- Governed pieces:
draft: true✓ · labelsneeds-user-decision,skip-changeset,documentation,size/s✓ · 速读 = one comment (5588349195), edited in place 16:40:34Z, now titled 「补丁轮后,heade1edc4196」 ✓ · reviewershotlong,os-zhuang✓ ·mergeable_state: blocked(draft + required review, expected). - Commits (3):
bd26a0839ande1edc4196carryCo-Authored-By+Claude-Sessiononly;b5be3f049is a plainMerge remote-tracking branch 'origin/main'(no trailers). No closing keyword /Part-of/Refsin any commit — RULE 2 ofcheck-partof-closing-keyword.mjsclean; CIPart-of PR must not also close its cardsuccess. - CI on
e1edc4196(get_check_runs, read once at 16:44Z): 24 runs — 11success, 9skipped, 0 failures, 4 stillin_progress(Lint & Repo Gates102149754082,Type Check · debt ledger102149754452,Type Check · consumer gates102149754376,Type Check · source gates102149754362; all started 16:39:36Z). Not a green reading; the director seat re-reads before recording. The diff is markdown-only under.claude/**, outside eslint'sfilespopulation, so none of the four can vary with it. - 速读 wording 「闸门只收紧不放松」, checked line by line for what a seat may do without a review: nothing is loosened. :514 / cli:18 / core-rules:113 lower the build tier (the change itself) while every one of them keeps the at-tier review as the mandate; :639 and core-rules:124 convert a tier predicate into a PASS requirement — a narrowing for at-tier builds (the gate line itself now demands the PASS) and, for below-tier builds, the absolute bar of the literal old text becomes PASS-gated, which is exactly the replacing guarantee; the deleted :522 half's guarantees live at
SKILL.md:526,:646-647andcontract-review.md:60(降档保险丝, byte-identical). The claim holds.
Findings
-
[minor — the one owed item] The PR body still describes
bd26a0839and now contradicts the head. One1edc4196the body says 「One file,.claude/skills/pm-dispatch/SKILL.md, 5 insertions / 5 deletions」, its table is headed 「after (bd26a0839)」, its :675 row quotes the superseded sentence, the 「Adjacent cards」 section says pm-dispatch: a contract-review verdict without the label handoff is invisible to every seat — name the FAIL end-state in one sentence, and add H51 for "verdict posted on this head, carrier still on" #16836'sreferences/contract-review.mdis not touched (it is: 3 lines), and neither the fivereferences/**rewrites norcore-rules.md:124nor the :639 consequence appear anywhere in it. The 速读 tells the maintainer 「读 PR 正文里 11 行的 before/after 与「每条删行的内容现在住哪」」 — the body holds 6 rows for 1 file. The director's item 1 asked for the pm-dispatch: a contract-review verdict without the label handoff is invisible to every seat — name the FAIL end-state in one sentence, and add H51 for "verdict posted on this head, carrier still on" #16836 overlap 「in the body」; F2's expectation named the body too. A governed PR is ruled on by the maintainer reading the body; a body that affirmatively states the wrong file surface is a record defect even though every line of the head is right.
Expectation: rewrite the PR body fore1edc4196— 4 files / 11 lines with the sixreferences/**rows added to the before/after table, 「Where each deleted piece lives now」 kept, the :639 consequence sentence (as in 速读 ②), pm-dispatch: a contract-review verdict without the label handoff is invisible to every seat — name the FAIL end-state in one sentence, and add H51 for "verdict posted on this head, carrier still on" #16836 disclosed as touched, its claimant re-merges, pm(dispatch-gates): clause-② prose in dispatch-gates.mjs (docblocks + every--tierprintout) and core-rules.md:124 still describes a BUILD-tier mandate once the 强制条款② narrowing lands #16914 as re-scoped. Do it the way AGENTS.md:432 prescribes: send the footer you want stored (strip the appended block first), passdraft: trueexplicitly (platform-readings.md:41—update_pull_requestsends the draft bit whether or not you pass it), read the body back. No push, no head move, no CI round; the director seat can verify the body against this table without a second tier review. -
[info, non-blocking] Merge commit
b5be3f049carries no trailers (authorClaude <noreply@anthropic.com>). AGENTS.md:517/542 sanctiongit merge origin/mainon a PR branch and AGENTS.md:578 exempts the merge commit itself; no closing keyword anywhere, so nothing for RULE 2. Recorded so the squash-merge author does not read the three-commit shape as two. -
[info, non-blocking] The frozen comparison arm of :675 is a sample of one. 「改制前达档史值」 is, per the card and the 速读, 1 FAIL / 1 at-tier-built clause-② card (objectui#8583 / PR
sys_position's shipped en bundle still asserts installation-wide uniqueness that #8556 corrected at source #8601). The 速读 discloses this (「样本一,不是基线」); the line itself no longer says 「基线待测」. Acceptable because the output is a decision card to the maintainer, who judges the n — but the report seat should carry the n alongside the rate so the card is not read as a threshold breach on 1 vs 1. -
[info] 速读 says 「回滚 = revert 本 PR 两个 commit」. The PR has three commits; the merge commit has no changes of its own, so reverting the two content commits is the correct recipe. Neutral.
Maintainer-only merge: yes (governed .claude/skills/**)
Generated by Claude Code
Fixes #16905
Governed surface — draft only.
.claude/skills/**is governed (AGENTS.md Prime Directive #14): this PR stays draft, carriesneeds-user-decision, a 「维护者速读」 comment (5588349195, edited in place after the patch round), and review requests toos-zhuangandhotlong; no seat approves, undrafts, queues or arms auto-merge.SKILL.mdis itself a 强制条款① surface, so this PR was built atCONTRACT_REVIEW_TIER(dispatch claim comment 5588071161) — the change cannot exempt its own landing.Patch round (head
e1edc4196) after the tier contract review (comment 5588464964, CHANGES REQUIRED); body refreshed for this head after the re-review (5588691266) read a copy predating the 16:47Z body write — the head itself is unchanged: the director seat widened the file surface toreferences/contract-review.md,references/core-rules.mdandreferences/lanes/cli.md, so thereferences/**copies of the build mandate are rewritten here, line-neutral; the :639 consequence is stated below; the :675 tripwire has an actor and a frozen comparison arm.origin/main(70f7d6d73) merged in as a merge commit (b5be3f049, plainMerge remote-tracking branch, no trailers, no content of its own), no conflicts, no overlap with these files; the two content commits arebd26a0839ande1edc4196, and reverting those two is the rollback recipe.What changes
Four files under
.claude/skills/pm-dispatch/, 11 insertions / 11 deletions, every file keeps its line count under its own shrink-only ratchet ceiling:SKILL.md811 → 811,references/contract-review.md60 → 60,references/core-rules.md150 → 150,references/lanes/cli.md29 → 29; every rewritten line is within the 120-byte budget (widths in the table). 强制条款② goes from "clause-② cards are built AND reviewed atCONTRACT_REVIEW_TIER" to "built at the default judgment tier, reviewed atCONTRACT_REVIEW_TIER", and everyreferences/**sentence that still described a build/dispatch mandate now says the mandate governs the review tier only. Untouched: 强制条款① (SKILL.md main file, the decision-frame copy,.claude/agents/os-dev.md); the carrier discipline (needs:contract-reviewon card and PR, cleared only by a posted verdict at tier; SKILL.md :646-647 byte-identical); the tier fusereferences/contract-review.md:60;references/lanes/spec.md's dispatch criteria; the four-axis frame block (SKILL.md :734-752, md522f2339f0acb64cdb50c7adc9db681c3on merge-base, on head, and on currentorigin/main).Exact before / after of every changed line (merge-base
0939ba008→ heade1edc4196)- 强制条款②:凡放宽接受集或扩大公开面的卡一律契约复审档;拉回已声明契约按常规档。- 强制条款②:凡放宽接受集或扩大公开面的卡默认判断档施工、契约复审档复核。- 条款②只指已发布契约面。- 条款②只指已发布契约面,拉回已声明契约不触它;卡面复述仍是条款②。- 卡面对条款②的复述仍是条款②;额度耗尽豁免及其needs:contract-review补偿一并及于它。- 契约复审档留给裁决/复审子代理、skills 席与条款②工作。- 契约复审档留给裁决/复审子代理、skills 席与条款②复核。---tier嫌疑行是提示非裁定;双肢命中任一且派发档位低于契约复审档 ⇒ ⛔ 禁止入队。---tier嫌疑行是提示非裁定;双肢命中任一 ⇒ 无席内契约复审档 PASS 在案 ⛔ 禁止入队。- 报告席记条款②默认档 FAIL 率入复审清单;超改制前达档史值 ⇒ 决策卡交维护者定回退。-Clause-②: yes按设计临时:只定派发档位的保守方向,⛔ 非终审。-Clause-②: yes- 机械地板 claim 时可查树:新导出符号或已发布载荷上的新键恒yes,直接锁契约复审档。- 机械地板 claim 时可查树:新导出符号或已发布载荷上的新键恒yes,锁契约复审档复核。- claim 拿不准 ⇒ 按yes派契约复审档;⛔ 不建全量分类学与 claim 时决策程序。- claim 拿不准 ⇒ 按yes挂标走契约复审档复核;⛔ 不建全量分类学与 claim 时决策程序。- 一单一次派发调用,档位逐卡显式传参,协议语义面与契约变更卡恒走契约复审档。- 一单一次派发调用,档位逐卡显式传参;语义面卡恒契约复审档施工,契约变更卡恒其复核。- 受管面 PR 留 draft 并向两个授权批准账户请审;档位不足的契约卡 ⛔ 禁止入队。- 受管面 PR 留 draft 并向两个授权批准账户请审;无达档复核 PASS 的契约卡 ⛔ 禁止入队。-dispatch-gates.mjs只报路径推导的地板,条款②从卡内容判且优先于它。-dispatch-gates.mjs只报路径推导的地板;条款②从卡内容判,只定复核档不定施工档。Where each deleted or replaced piece of content lives now
lanes/spec.md:19「收窄仍是语义面,不触条款②」), so it carries neither the mandated review nor a tier mandate — "按常规档" is now every card's default and distinguishes nothing.needs:contract-review补偿一并及于它」 → genuinely redundant: the exemption floor is the default judgment tier (:526 「⛔ 不再往下」), now the clause-② build tier anyway; the carrier hangs on everyClause-②: yescard regardless of tier (:646-647); the review never downgrades (contract-review.md:60). No guarantee is lost.contract-review.md:41落地前检①). Consequence, stated for the maintainer to rule on knowingly: the rewritten gate makes an in-seatCONTRACT_REVIEW_TIERPASS on record the sole exit for every path-limb hit (diff touchingpackages/spec/src/**), includingClause-②: nospec-lane PRs and at-tier builds — stricter than skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912's recorded current practice (fix(spec): isValueDomainMember refuses an off-vocabulary domain instead of failing open #16899 / docs(spec): say on the title grade which INPUT it describes #16901 enqueued oncheck-clause2-carriers --pairexit 0 without a PASS) and stricter than skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912's own suggested wording, consistent withlanes/spec.md:33「条款②路径肢照命中,入队前仍过契约复核」 and with 「按更严的一条行动」. If that is not intended, :639 needs 「判定yes」 inserted before the PASS clause. skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912 remains open; this PR does not decide it.contract-review.md:40); the comparison arm is the historical at-tier-built FAIL rate frozen before this change (改制前达档史值 — today n = 1: 1 FAIL / 1 at-tier-built clause-② card, objectui#8583 / PRsys_position's shipped en bundle still asserts installation-wide uniqueness that #8556 corrected at source #8601; a sample of one, ⛔ not a baseline); the report seat carries the n alongside the rate on both arms so a card is never read as a threshold breach on 1 vs 1; exceeding it produces a decision card to the maintainer, who judges the n and decides the revert — never a seat act.The tripwire (ruling item 3)
SKILL.md :675 as above. No new script, label or state; the record lands in the round report's 复审清单, the revert is a decision-box card.
Mechanism hypotheses (verified on
origin/main@0939ba008)references/contract-review.md:60: 「契约复核 ⛔ 不适用额度耗尽豁免降档:豁免对象是派发,复核正为补偿低档派发而存在。」 andscripts/pm/dispatch-gates.mjsMANDATORY_TIER_GLOBSdocblock: "references-only surfaces carry NO path mandate any more (opus execution, compensated by the skill-face review at CONTRACT_REVIEW_TIER)", recording the 2026-08-20 ruling 「fable 当审计师用,不当施工队用」. Both sanction low-tier build + at-tier review.check:skill-frame-syncandcheck:skill-frame-freshnessexit 0.references/lanes/skills.md:20「条款②闸门照现行」 points at the enqueue gate (kept); 「pm-dispatch 根恒契约复审档」 is 条款①. Not edited.deriveTierencodes clause ① globs only. The script'sCONTRACT_REVIEW_TIERdocblock ("must be dispatched at"),MANDATORY_TIER_GLOBSdocblock ("is also CONTRACT_REVIEW_TIER") and thetierLinesstrings printed on every--tierrun ("is fable-mandatory too") still describe a BUILD-tier mandate.scripts/pm/**stays out of surface; filed as pm(dispatch-gates): clause-② prose in dispatch-gates.mjs (docblocks + every--tierprintout) and core-rules.md:124 still describes a BUILD-tier mandate once the 强制条款② narrowing lands #16914 (finding,Blocked-by:this card), whose body was re-scoped in this round to the script prose only now that thereferences/**sites are rewritten in this PR; pm(dispatch-gates): clause-② prose in dispatch-gates.mjs (docblocks + every--tierprintout) and core-rules.md:124 still describes a BUILD-tier mandate once the 强制条款② narrowing lands #16914 remains open.Adjacent cards
references/contract-review.md, which this PR now edits at :10 / :13 / :15 — its future claimant re-merges onto this.Changeset
skip-changeset, per AGENTS.md Post-Task Checklist item 3: "that label is for a diff that publishes nothing from any released package.".claude/skills/**is not part of any released package (the published skills live inskills/**). Nocontent/docs/releases/**touched.Gates on head
e1edc4196(exit captured before any pipe; verdict lines quoted from the gate)pnpm check:pm-skill-ratchetSKILL.md is 811 lines (ceiling 811; headroom 0)·contract-review.md is 60 lines (ceiling 60; headroom 0)·core-rules.md is 150 lines (ceiling 150; headroom 0)·lanes/cli.md is 29 lines (ceiling 29; headroom 0)pnpm check:skill-frame-sync✓ check-skill-frame-sync: 2 copies of the decision frame are structurally isomorphic across 2 filespnpm check:skill-frame-freshness✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).pnpm check:pm-skill-id-lint✓ check-skill-id-lint: 26 file(s) clean (pattern /#[0-9]{3,}/g).pnpm check:nul-bytescheck-nul-bytes: OK (scanned 8369 text file(s) … no raw ASCII control bytes).node scripts/check-closing-keyword-parity.mjs(+--self-test)check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords …)node scripts/check-comment-mask-corpus.mjs✓ comment-mask corpus sweep: 6381 files, 0 disagree, 0 unparseablenode scripts/pm/check-governed-queue-guard.mjs --self-test✓ check-governed-queue-guard self-test: 144 cases passpnpm --filter @objectstack/lint run check:doc-formula-expressions✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 434 files / 1373 TS blocks judged clean(prerequisite build of@objectstack/formula+@objectstack/lintunderos-verify-lock.sh:VERDICT command-exit 0 · held the lock 203s)pnpm check:agent-test-spelling✓ check-agent-test-spelling: 0 violationspnpm check:doc-authoring✓ doc authoring guard: 46 published skill files cleanpnpm check:driver-memory-censuscheck-driver-memory-census: OKpnpm check:pm-governed-mergespnpm check:pm-governed-prose✓ check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfacespnpm check:refd-timer-probe✓ check-refd-timer-probe self-test: 11 cases passpnpm check:watch-hint-literal✓ check-watch-hint-literal: 66 declaration(s) across 4 rostered name(s)node scripts/pm/dispatch-gates.mjs --ran✓ dispatch-gates --ran: 16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED.—derived from the tree … at commit e1edc4196The 16 derived families and the doc-formula / comment-mask / governed-* runs were taken on the working tree that became
e1edc4196(identical bytes, before the commit existed); the ratchet family, frame-sync, id-lint, nul-bytes and--ranwere re-run on the committed head and are the readings quoted above. Control-character self-scan of the four edited files: 0 lines.pnpm lint(eslint) is CI's run and was not run locally; its population isfiles: ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}'](eslint.config.mjs:971), which this markdown-only diff does not enter — a population reading, not a run. No package test suite is affected (.claude/**-only diff); CI runs the full farm on the PR.Generated by Claude Code